agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v3 09/10] ci: windows: Disabling write cache flushing during test 466+ messages / 3 participants [nested] [flat]
* [PATCH v3 09/10] ci: windows: Disabling write cache flushing during test @ 2023-08-07 23:56 Andres Freund <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Andres Freund @ 2023-08-07 23:56 UTC (permalink / raw) This has been measured to reduce windows test times by about 30s. --- .cirrus.tasks.yml | 6 ++++++ src/tools/ci/windows_write_cache.ps1 | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/tools/ci/windows_write_cache.ps1 diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml index d1730ce08a8..360b1c775fd 100644 --- a/.cirrus.tasks.yml +++ b/.cirrus.tasks.yml @@ -547,6 +547,12 @@ task: setup_additional_packages_script: | REM choco install -y --no-progress ... + # Define the write cache to be power protected. This reduces the rate of + # cache flushes, which seems to help metadata heavy workloads on NTFS. We're + # just testing here anyway, so ... + change_write_caching_script: + - powershell src/tools/ci/windows_write_cache.ps1 2>&1 + setup_hosts_file_script: | echo 127.0.0.1 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts echo 127.0.0.2 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts diff --git a/src/tools/ci/windows_write_cache.ps1 b/src/tools/ci/windows_write_cache.ps1 new file mode 100644 index 00000000000..5c67b3ce54b --- /dev/null +++ b/src/tools/ci/windows_write_cache.ps1 @@ -0,0 +1,20 @@ +# Define the write cache to be power protected. This reduces the rate of cache +# flushes, which seems to help metadata heavy workloads on NTFS. We're just +# testing here anyway, so ... +# +# Let's do so for all disks, this could be useful beyond cirrus-ci. + +Set-Location "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI"; + +Get-ChildItem -Path "*/*" | foreach-object { + Push-Location; + cd /$_; + pwd; + cd 'Device Parameters'; + if (!(Test-Path -Path "Disk")) { + New-Item -Path "Disk"; + } + + Set-ItemProperty -Path Disk -Type DWord -name CacheIsPowerProtected -Value 1; + Pop-Location; +} -- 2.38.0 --uh2yukyzfvojbe2k Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0010-regress-Check-for-postgres-startup-completion-mor.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 09/10] ci: windows: Disabling write cache flushing during test @ 2023-08-07 23:56 Andres Freund <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Andres Freund @ 2023-08-07 23:56 UTC (permalink / raw) This has been measured to reduce windows test times by about 30s. --- .cirrus.tasks.yml | 6 ++++++ src/tools/ci/windows_write_cache.ps1 | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/tools/ci/windows_write_cache.ps1 diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml index d1730ce08a8..360b1c775fd 100644 --- a/.cirrus.tasks.yml +++ b/.cirrus.tasks.yml @@ -547,6 +547,12 @@ task: setup_additional_packages_script: | REM choco install -y --no-progress ... + # Define the write cache to be power protected. This reduces the rate of + # cache flushes, which seems to help metadata heavy workloads on NTFS. We're + # just testing here anyway, so ... + change_write_caching_script: + - powershell src/tools/ci/windows_write_cache.ps1 2>&1 + setup_hosts_file_script: | echo 127.0.0.1 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts echo 127.0.0.2 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts diff --git a/src/tools/ci/windows_write_cache.ps1 b/src/tools/ci/windows_write_cache.ps1 new file mode 100644 index 00000000000..5c67b3ce54b --- /dev/null +++ b/src/tools/ci/windows_write_cache.ps1 @@ -0,0 +1,20 @@ +# Define the write cache to be power protected. This reduces the rate of cache +# flushes, which seems to help metadata heavy workloads on NTFS. We're just +# testing here anyway, so ... +# +# Let's do so for all disks, this could be useful beyond cirrus-ci. + +Set-Location "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI"; + +Get-ChildItem -Path "*/*" | foreach-object { + Push-Location; + cd /$_; + pwd; + cd 'Device Parameters'; + if (!(Test-Path -Path "Disk")) { + New-Item -Path "Disk"; + } + + Set-ItemProperty -Path Disk -Type DWord -name CacheIsPowerProtected -Value 1; + Pop-Location; +} -- 2.38.0 --uh2yukyzfvojbe2k Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0010-regress-Check-for-postgres-startup-completion-mor.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test @ 2023-08-07 23:56 Andres Freund <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Andres Freund @ 2023-08-07 23:56 UTC (permalink / raw) This has been measured to reduce windows test times by about 30s. --- .cirrus.yml | 2 ++ src/tools/ci/windows_write_cache.ps1 | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 src/tools/ci/windows_write_cache.ps1 diff --git a/.cirrus.yml b/.cirrus.yml index 35ef9c97211..ef825485826 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -559,6 +559,8 @@ task: setup_additional_packages_script: | REM choco install -y --no-progress ... + change_write_caching_script: powershell src/tools/ci/windows_write_cache.ps1 + setup_hosts_file_script: | echo 127.0.0.1 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts echo 127.0.0.2 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts diff --git a/src/tools/ci/windows_write_cache.ps1 b/src/tools/ci/windows_write_cache.ps1 new file mode 100644 index 00000000000..9c52bc886d4 --- /dev/null +++ b/src/tools/ci/windows_write_cache.ps1 @@ -0,0 +1,3 @@ +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected +Set-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -Value 0 +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -- 2.38.0 --uu4yojthqnm7ulmd Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0007-regress-Check-for-postgres-startup-completion-mor.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test @ 2023-08-07 23:56 Andres Freund <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Andres Freund @ 2023-08-07 23:56 UTC (permalink / raw) This has been measured to reduce windows test times by about 30s. --- .cirrus.yml | 2 ++ src/tools/ci/windows_write_cache.ps1 | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 src/tools/ci/windows_write_cache.ps1 diff --git a/.cirrus.yml b/.cirrus.yml index 35ef9c97211..ef825485826 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -559,6 +559,8 @@ task: setup_additional_packages_script: | REM choco install -y --no-progress ... + change_write_caching_script: powershell src/tools/ci/windows_write_cache.ps1 + setup_hosts_file_script: | echo 127.0.0.1 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts echo 127.0.0.2 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts diff --git a/src/tools/ci/windows_write_cache.ps1 b/src/tools/ci/windows_write_cache.ps1 new file mode 100644 index 00000000000..9c52bc886d4 --- /dev/null +++ b/src/tools/ci/windows_write_cache.ps1 @@ -0,0 +1,3 @@ +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected +Set-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -Value 0 +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -- 2.38.0 --uu4yojthqnm7ulmd Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0007-regress-Check-for-postgres-startup-completion-mor.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test @ 2023-08-07 23:56 Andres Freund <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Andres Freund @ 2023-08-07 23:56 UTC (permalink / raw) This has been measured to reduce windows test times by about 30s. --- .cirrus.yml | 2 ++ src/tools/ci/windows_write_cache.ps1 | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 src/tools/ci/windows_write_cache.ps1 diff --git a/.cirrus.yml b/.cirrus.yml index 35ef9c97211..ef825485826 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -559,6 +559,8 @@ task: setup_additional_packages_script: | REM choco install -y --no-progress ... + change_write_caching_script: powershell src/tools/ci/windows_write_cache.ps1 + setup_hosts_file_script: | echo 127.0.0.1 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts echo 127.0.0.2 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts diff --git a/src/tools/ci/windows_write_cache.ps1 b/src/tools/ci/windows_write_cache.ps1 new file mode 100644 index 00000000000..9c52bc886d4 --- /dev/null +++ b/src/tools/ci/windows_write_cache.ps1 @@ -0,0 +1,3 @@ +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected +Set-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -Value 0 +Get-ItemProperty -path "HKLM:/SYSTEM/CurrentControlSet/Enum/SCSI/*/*/Device Parameters/Disk" -name CacheIsPowerProtected -- 2.38.0 --uu4yojthqnm7ulmd Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0007-regress-Check-for-postgres-startup-completion-mor.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v17 5/8] Row pattern recognition patch (executor). @ 2024-04-28 11:00 Tatsuo Ishii <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Tatsuo Ishii @ 2024-04-28 11:00 UTC (permalink / raw) --- src/backend/executor/nodeWindowAgg.c | 1610 +++++++++++++++++++++++++- src/backend/utils/adt/windowfuncs.c | 37 +- src/include/catalog/pg_proc.dat | 6 + src/include/nodes/execnodes.h | 30 + 4 files changed, 1671 insertions(+), 12 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 3221fa1522..140bb3941e 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -36,6 +36,7 @@ #include "access/htup_details.h" #include "catalog/objectaccess.h" #include "catalog/pg_aggregate.h" +#include "catalog/pg_collation_d.h" #include "catalog/pg_proc.h" #include "executor/executor.h" #include "executor/nodeWindowAgg.h" @@ -48,6 +49,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/datum.h" +#include "utils/fmgroids.h" #include "utils/expandeddatum.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -159,6 +161,43 @@ typedef struct WindowStatePerAggData bool restart; /* need to restart this agg in this cycle? */ } WindowStatePerAggData; +/* + * Set of StringInfo. Used in RPR. + */ +typedef struct StringSet +{ + StringInfo *str_set; + Size set_size; /* current array allocation size in number of + * items */ + int set_index; /* current used size */ +} StringSet; + +/* + * Allowed subsequent PATTERN variables positions. + * Used in RPR. + * + * pos represents the pattern variable defined order in DEFINE caluase. For + * example. "DEFINE START..., UP..., DOWN ..." and "PATTERN START UP DOWN UP" + * will create: + * VariablePos[0].pos[0] = 0; START + * VariablePos[1].pos[0] = 1; UP + * VariablePos[1].pos[1] = 3; UP + * VariablePos[2].pos[0] = 2; DOWN + * + * Note that UP has two pos because UP appears in PATTERN twice. + * + * By using this strucrture, we can know which pattern variable can be followed + * by which pattern variable(s). For example, START can be followed by UP and + * DOWN since START's pos is 0, and UP's pos is 1 or 3, DOWN's pos is 2. + * DOWN can be followed by UP since UP's pos is either 1 or 3. + * + */ +#define NUM_ALPHABETS 26 /* we allow [a-z] variable initials */ +typedef struct VariablePos +{ + int pos[NUM_ALPHABETS]; /* postion(s) in PATTERN */ +} VariablePos; + static void initialize_windowaggregate(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate); @@ -184,6 +223,7 @@ static void release_partition(WindowAggState *winstate); static int row_is_in_frame(WindowAggState *winstate, int64 pos, TupleTableSlot *slot); + static void update_frameheadpos(WindowAggState *winstate); static void update_frametailpos(WindowAggState *winstate); static void update_grouptailpos(WindowAggState *winstate); @@ -195,9 +235,48 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype); static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, TupleTableSlot *slot2); + +static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout); static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot); +static void attno_map(Node *node); +static bool attno_map_walker(Node *node, void *context); +static int row_is_in_reduced_frame(WindowObject winobj, int64 pos); +static bool rpr_is_defined(WindowAggState *winstate); + +static void create_reduced_frame_map(WindowAggState *winstate); +static int get_reduced_frame_map(WindowAggState *winstate, int64 pos); +static void register_reduced_frame_map(WindowAggState *winstate, int64 pos, + int val); +static void clear_reduced_frame_map(WindowAggState *winstate); +static void update_reduced_frame(WindowObject winobj, int64 pos); + +static int64 evaluate_pattern(WindowObject winobj, int64 current_pos, + char *vname, StringInfo encoded_str, bool *result); + +static bool get_slots(WindowObject winobj, int64 current_pos); + +static int search_str_set(char *pattern, StringSet * str_set, + VariablePos * variable_pos); +static char pattern_initial(WindowAggState *winstate, char *vname); +static int do_pattern_match(char *pattern, char *encoded_str); + +static StringSet * string_set_init(void); +static void string_set_add(StringSet * string_set, StringInfo str); +static StringInfo string_set_get(StringSet * string_set, int index); +static int string_set_get_size(StringSet * string_set); +static void string_set_discard(StringSet * string_set); +static VariablePos * variable_pos_init(void); +static void variable_pos_register(VariablePos * variable_pos, char initial, + int pos); +static bool variable_pos_compare(VariablePos * variable_pos, + char initial1, char initial2); +static int variable_pos_fetch(VariablePos * variable_pos, char initial, + int index); +static void variable_pos_discard(VariablePos * variable_pos); /* * initialize_windowaggregate @@ -774,10 +853,12 @@ eval_windowaggregates(WindowAggState *winstate) * transition function, or * - we have an EXCLUSION clause, or * - if the new frame doesn't overlap the old one + * - if RPR is enabled * * Note that we don't strictly need to restart in the last case, but if * we're going to remove all rows from the aggregation anyway, a restart * surely is faster. + * we restart aggregation too. *---------- */ numaggs_restart = 0; @@ -788,7 +869,8 @@ eval_windowaggregates(WindowAggState *winstate) (winstate->aggregatedbase != winstate->frameheadpos && !OidIsValid(peraggstate->invtransfn_oid)) || (winstate->frameOptions & FRAMEOPTION_EXCLUSION) || - winstate->aggregatedupto <= winstate->frameheadpos) + winstate->aggregatedupto <= winstate->frameheadpos || + rpr_is_defined(winstate)) { peraggstate->restart = true; numaggs_restart++; @@ -862,7 +944,22 @@ eval_windowaggregates(WindowAggState *winstate) * head, so that tuplestore can discard unnecessary rows. */ if (agg_winobj->markptr >= 0) - WinSetMarkPosition(agg_winobj, winstate->frameheadpos); + { + int64 markpos = winstate->frameheadpos; + + if (rpr_is_defined(winstate)) + { + /* + * If RPR is used, it is possible PREV wants to look at the + * previous row. So the mark pos should be frameheadpos - 1 + * unless it is below 0. + */ + markpos -= 1; + if (markpos < 0) + markpos = 0; + } + WinSetMarkPosition(agg_winobj, markpos); + } /* * Now restart the aggregates that require it. @@ -917,6 +1014,14 @@ eval_windowaggregates(WindowAggState *winstate) { winstate->aggregatedupto = winstate->frameheadpos; ExecClearTuple(agg_row_slot); + + /* + * If RPR is defined, we do not use aggregatedupto_nonrestarted. To + * avoid assertion failure below, we reset aggregatedupto_nonrestarted + * to frameheadpos. + */ + if (rpr_is_defined(winstate)) + aggregatedupto_nonrestarted = winstate->frameheadpos; } /* @@ -930,6 +1035,12 @@ eval_windowaggregates(WindowAggState *winstate) { int ret; +#ifdef RPR_DEBUG + elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT, + winstate->aggregatedupto, + winstate->aggregatedbase); +#endif + /* Fetch next row if we didn't already */ if (TupIsNull(agg_row_slot)) { @@ -945,9 +1056,52 @@ eval_windowaggregates(WindowAggState *winstate) ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot); if (ret < 0) break; + if (ret == 0) goto next_tuple; + if (rpr_is_defined(winstate)) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT, + get_reduced_frame_map(winstate, + winstate->aggregatedupto), + winstate->aggregatedupto, + winstate->aggregatedbase); +#endif + /* + * If the row status at currentpos is already decided and current + * row status is not decided yet, it means we passed the last + * reduced frame. Time to break the loop. + */ + if (get_reduced_frame_map(winstate, + winstate->currentpos) != RF_NOT_DETERMINED && + get_reduced_frame_map(winstate, + winstate->aggregatedupto) == RF_NOT_DETERMINED) + break; + + /* + * Otherwise we need to calculate the reduced frame. + */ + ret = row_is_in_reduced_frame(winstate->agg_winobj, + winstate->aggregatedupto); + if (ret == -1) /* unmatched row */ + break; + + /* + * Check if current row needs to be skipped due to no match. + */ + if (get_reduced_frame_map(winstate, + winstate->aggregatedupto) == RF_SKIPPED && + winstate->aggregatedupto == winstate->aggregatedbase) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "skip current row for aggregation"); +#endif + break; + } + } + /* Set tuple context for evaluation of aggregate arguments */ winstate->tmpcontext->ecxt_outertuple = agg_row_slot; @@ -976,6 +1130,7 @@ next_tuple: ExecClearTuple(agg_row_slot); } + /* The frame's end is not supposed to move backwards, ever */ Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto); @@ -995,7 +1150,6 @@ next_tuple: &winstate->perfunc[wfuncno], peraggstate, result, isnull); - /* * save the result in case next row shares the same frame. * @@ -1090,6 +1244,7 @@ begin_partition(WindowAggState *winstate) winstate->framehead_valid = false; winstate->frametail_valid = false; winstate->grouptail_valid = false; + create_reduced_frame_map(winstate); winstate->spooled_rows = 0; winstate->currentpos = 0; winstate->frameheadpos = 0; @@ -2053,6 +2208,11 @@ ExecWindowAgg(PlanState *pstate) CHECK_FOR_INTERRUPTS(); +#ifdef RPR_DEBUG + elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT, + winstate->currentpos); +#endif + if (winstate->status == WINDOWAGG_DONE) return NULL; @@ -2221,6 +2381,17 @@ ExecWindowAgg(PlanState *pstate) /* don't evaluate the window functions when we're in pass-through mode */ if (winstate->status == WINDOWAGG_RUN) { + /* + * If RPR is defined and skip mode is next row, we need to clear + * existing reduced frame info so that we newly calculate the info + * starting from current row. + */ + if (rpr_is_defined(winstate)) + { + if (winstate->rpSkipTo == ST_NEXT_ROW) + clear_reduced_frame_map(winstate); + } + /* * Evaluate true window functions */ @@ -2388,6 +2559,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) TupleDesc scanDesc; ListCell *l; + TargetEntry *te; + Expr *expr; + /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -2486,6 +2660,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc, &TTSOpsMinimalTuple); + winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + + winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + + winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot); + /* * create frame head and tail slots only if needed (must create slots in * exactly the same cases that update_frameheadpos and update_frametailpos @@ -2667,6 +2851,43 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) winstate->inRangeAsc = node->inRangeAsc; winstate->inRangeNullsFirst = node->inRangeNullsFirst; + /* Set up SKIP TO type */ + winstate->rpSkipTo = node->rpSkipTo; + /* Set up row pattern recognition PATTERN clause */ + winstate->patternVariableList = node->patternVariable; + winstate->patternRegexpList = node->patternRegexp; + + /* Set up row pattern recognition DEFINE clause */ + winstate->defineInitial = node->defineInitial; + winstate->defineVariableList = NIL; + winstate->defineClauseList = NIL; + if (node->defineClause != NIL) + { + /* + * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot. + */ + foreach(l, node->defineClause) + { + char *name; + ExprState *exps; + + te = lfirst(l); + name = te->resname; + expr = te->expr; + +#ifdef RPR_DEBUG + elog(DEBUG1, "defineVariable name: %s", name); +#endif + winstate->defineVariableList = + lappend(winstate->defineVariableList, + makeString(pstrdup(name))); + attno_map((Node *) expr); + exps = ExecInitExpr(expr, (PlanState *) winstate); + winstate->defineClauseList = + lappend(winstate->defineClauseList, exps); + } + } + winstate->all_first = true; winstate->partition_spooled = false; winstate->more_partitions = false; @@ -2674,6 +2895,64 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) return winstate; } +/* + * Rewrite varno of Var node that is the argument of PREV/NET so that it sees + * scan tuple (PREV) or inner tuple (NEXT). + */ +static void +attno_map(Node *node) +{ + (void) expression_tree_walker(node, attno_map_walker, NULL); +} + +static bool +attno_map_walker(Node *node, void *context) +{ + FuncExpr *func; + int nargs; + Expr *expr; + Var *var; + + if (node == NULL) + return false; + + if (IsA(node, FuncExpr)) + { + func = (FuncExpr *) node; + + if (func->funcid == F_PREV || func->funcid == F_NEXT) + { + /* sanity check */ + nargs = list_length(func->args); + if (list_length(func->args) != 1) + elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", + func->funcid, nargs); + + expr = (Expr *) lfirst(list_head(func->args)); + if (!IsA(expr, Var)) + elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible + * that arg type is + * Const? */ + var = (Var *) expr; + + if (func->funcid == F_PREV) + + /* + * Rewrite varno from OUTER_VAR to regular var no so that the + * var references scan tuple. + */ + var->varno = var->varnosyn; + else + var->varno = INNER_VAR; + +#ifdef RPR_DEBUG + elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno); +#endif + } + } + return expression_tree_walker(node, attno_map_walker, NULL); +} + /* ----------------- * ExecEndWindowAgg * ----------------- @@ -2723,6 +3002,8 @@ ExecReScanWindowAgg(WindowAggState *node) ExecClearTuple(node->agg_row_slot); ExecClearTuple(node->temp_slot_1); ExecClearTuple(node->temp_slot_2); + ExecClearTuple(node->prev_slot); + ExecClearTuple(node->next_slot); if (node->framehead_slot) ExecClearTuple(node->framehead_slot); if (node->frametail_slot) @@ -3083,7 +3364,8 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot) return false; if (pos < winobj->markpos) - elog(ERROR, "cannot fetch row before WindowObject's mark position"); + elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, + pos, winobj->markpos); oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); @@ -3403,14 +3685,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, WindowAggState *winstate; ExprContext *econtext; TupleTableSlot *slot; - int64 abs_pos; - int64 mark_pos; Assert(WindowObjectIsValid(winobj)); winstate = winobj->winstate; econtext = winstate->ss.ps.ps_ExprContext; slot = winstate->temp_slot_1; + if (WinGetSlotInFrame(winobj, slot, + relpos, seektype, set_mark, + isnull, isout) == 0) + { + econtext->ecxt_outertuple = slot; + return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), + econtext, isnull); + } + + if (isout) + *isout = true; + *isnull = true; + return (Datum) 0; +} + +/* + * WinGetSlotInFrame + * slot: TupleTableSlot to store the result + * relpos: signed rowcount offset from the seek position + * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL + * set_mark: If the row is found/in frame and set_mark is true, the mark is + * moved to the row as a side-effect. + * isnull: output argument, receives isnull status of result + * isout: output argument, set to indicate whether target row position + * is out of frame (can pass NULL if caller doesn't care about this) + * + * Returns 0 if we successfullt got the slot. false if out of frame. + * (also isout is set) + */ +static int +WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout) +{ + WindowAggState *winstate; + int64 abs_pos; + int64 mark_pos; + int num_reduced_frame; + + Assert(WindowObjectIsValid(winobj)); + winstate = winobj->winstate; + switch (seektype) { case WINDOW_SEEK_CURRENT: @@ -3477,11 +3799,25 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, winstate->frameOptions); break; } + num_reduced_frame = row_is_in_reduced_frame(winobj, + winstate->frameheadpos); + if (num_reduced_frame < 0) + goto out_of_frame; + else if (num_reduced_frame > 0) + if (relpos >= num_reduced_frame) + goto out_of_frame; break; case WINDOW_SEEK_TAIL: /* rejecting relpos > 0 is easy and simplifies code below */ if (relpos > 0) goto out_of_frame; + + /* + * RPR cares about frame head pos. Need to call + * update_frameheadpos + */ + update_frameheadpos(winstate); + update_frametailpos(winstate); abs_pos = winstate->frametailpos - 1 + relpos; @@ -3548,6 +3884,14 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, mark_pos = 0; /* keep compiler quiet */ break; } + + num_reduced_frame = row_is_in_reduced_frame(winobj, + winstate->frameheadpos + relpos); + if (num_reduced_frame < 0) + goto out_of_frame; + else if (num_reduced_frame > 0) + abs_pos = winstate->frameheadpos + relpos + + num_reduced_frame - 1; break; default: elog(ERROR, "unrecognized window seek type: %d", seektype); @@ -3566,15 +3910,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, *isout = false; if (set_mark) WinSetMarkPosition(winobj, mark_pos); - econtext->ecxt_outertuple = slot; - return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), - econtext, isnull); + return 0; out_of_frame: if (isout) *isout = true; *isnull = true; - return (Datum) 0; + return -1; } /* @@ -3605,3 +3947,1251 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull) return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), econtext, isnull); } + +/* + * rpr_is_defined + * return true if Row pattern recognition is defined. + */ +static +bool +rpr_is_defined(WindowAggState *winstate) +{ + return winstate->patternVariableList != NIL; +} + +/* + * ----------------- + * row_is_in_reduced_frame + * Determine whether a row is in the current row's reduced window frame + * according to row pattern matching + * + * The row must has been already determined that it is in a full window frame + * and fetched it into slot. + * + * Returns: + * = 0, RPR is not defined. + * >0, if the row is the first in the reduced frame. Return the number of rows + * in the reduced frame. + * -1, if the row is unmatched row + * -2, if the row is in the reduced frame but needed to be skipped because of + * AFTER MATCH SKIP PAST LAST ROW + * ----------------- + */ +static +int +row_is_in_reduced_frame(WindowObject winobj, int64 pos) +{ + WindowAggState *winstate = winobj->winstate; + int state; + int rtn; + + if (!rpr_is_defined(winstate)) + { + /* + * RPR is not defined. Assume that we are always in the the reduced + * window frame. + */ + rtn = 0; +#ifdef RPR_DEBUG + elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, + rtn, pos); +#endif + return rtn; + } + + state = get_reduced_frame_map(winstate, pos); + + if (state == RF_NOT_DETERMINED) + { + update_frameheadpos(winstate); + update_reduced_frame(winobj, pos); + } + + state = get_reduced_frame_map(winstate, pos); + + switch (state) + { + int64 i; + int num_reduced_rows; + + case RF_FRAME_HEAD: + num_reduced_rows = 1; + for (i = pos + 1; + get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++) + num_reduced_rows++; + rtn = num_reduced_rows; + break; + + case RF_SKIPPED: + rtn = -2; + break; + + case RF_UNMATCHED: + rtn = -1; + break; + + default: + elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, + state, pos); + break; + } + +#ifdef RPR_DEBUG + elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, + rtn, pos); +#endif + return rtn; +} + +#define REDUCED_FRAME_MAP_INIT_SIZE 1024L + +/* + * create_reduced_frame_map + * Create reduced frame map + */ +static +void +create_reduced_frame_map(WindowAggState *winstate) +{ + winstate->reduced_frame_map = + MemoryContextAlloc(winstate->partcontext, + REDUCED_FRAME_MAP_INIT_SIZE); + winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE; + clear_reduced_frame_map(winstate); +} + +/* + * clear_reduced_frame_map + * Clear reduced frame map + */ +static +void +clear_reduced_frame_map(WindowAggState *winstate) +{ + Assert(winstate->reduced_frame_map != NULL); + MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED, + winstate->alloc_sz); +} + +/* + * get_reduced_frame_map + * Get reduced frame map specified by pos + */ +static +int +get_reduced_frame_map(WindowAggState *winstate, int64 pos) +{ + Assert(winstate->reduced_frame_map != NULL); + + if (pos < 0 || pos >= winstate->alloc_sz) + elog(ERROR, "wrong pos: " INT64_FORMAT, pos); + + return winstate->reduced_frame_map[pos]; +} + +/* + * register_reduced_frame_map + * Add/replace reduced frame map member at pos. + * If there's no enough space, expand the map. + */ +static +void +register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val) +{ + int64 realloc_sz; + + Assert(winstate->reduced_frame_map != NULL); + + if (pos < 0) + elog(ERROR, "wrong pos: " INT64_FORMAT, pos); + + if (pos > winstate->alloc_sz - 1) + { + realloc_sz = winstate->alloc_sz * 2; + + winstate->reduced_frame_map = + repalloc(winstate->reduced_frame_map, realloc_sz); + + MemSet(winstate->reduced_frame_map + winstate->alloc_sz, + RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz); + + winstate->alloc_sz = realloc_sz; + } + + winstate->reduced_frame_map[pos] = val; +} + +/* + * update_reduced_frame + * Update reduced frame info. + */ +static +void +update_reduced_frame(WindowObject winobj, int64 pos) +{ + WindowAggState *winstate = winobj->winstate; + ListCell *lc1, + *lc2; + bool expression_result; + int num_matched_rows; + int64 original_pos; + bool anymatch; + StringInfo encoded_str; + StringInfo pattern_str = makeStringInfo(); + StringSet *str_set; + int initial_index; + VariablePos *variable_pos; + bool greedy = false; + int64 result_pos, + i; + + /* + * Set of pattern variables evaluated to true. Each character corresponds + * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In + * this case at row 0 A and B are true, and A and C are true in row 1. + */ + + /* initialize pattern variables set */ + str_set = string_set_init(); + + /* save original pos */ + original_pos = pos; + + /* + * Check if the pattern does not include any greedy quantifier. If it does + * not, we can just apply the pattern to each row. If it succeeds, we are + * done. + */ + foreach(lc1, winstate->patternRegexpList) + { + char *quantifier = strVal(lfirst(lc1)); + + if (*quantifier == '+' || *quantifier == '*') + { + greedy = true; + break; + } + } + + /* + * Non greedy case + */ + if (!greedy) + { + num_matched_rows = 0; + + foreach(lc1, winstate->patternVariableList) + { + char *vname = strVal(lfirst(lc1)); + + encoded_str = makeStringInfo(); + +#ifdef RPR_DEBUG + elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s", + pos, vname); +#endif + expression_result = false; + + /* evaluate row pattern against current row */ + result_pos = evaluate_pattern(winobj, pos, vname, + encoded_str, &expression_result); + if (!expression_result || result_pos < 0) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "expression result is false or out of frame"); +#endif + register_reduced_frame_map(winstate, original_pos, + RF_UNMATCHED); + return; + } + /* move to next row */ + pos++; + num_matched_rows++; + } +#ifdef RPR_DEBUG + elog(DEBUG1, "pattern matched"); +#endif + register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD); + + for (i = original_pos + 1; i < original_pos + num_matched_rows; i++) + { + register_reduced_frame_map(winstate, i, RF_SKIPPED); + } + return; + } + + /* + * Greedy quantifiers included. Loop over until none of pattern matches or + * encounters end of frame. + */ + for (;;) + { + result_pos = -1; + + /* + * Loop over each PATTERN variable. + */ + anymatch = false; + encoded_str = makeStringInfo(); + + forboth(lc1, winstate->patternVariableList, lc2, + winstate->patternRegexpList) + { + char *vname = strVal(lfirst(lc1)); +#ifdef RPR_DEBUG + char *quantifier = strVal(lfirst(lc2)); + + elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", + pos, vname, quantifier); +#endif + expression_result = false; + + /* evaluate row pattern against current row */ + result_pos = evaluate_pattern(winobj, pos, vname, + encoded_str, &expression_result); + if (expression_result) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "expression result is true"); +#endif + anymatch = true; + } + + /* + * If out of frame, we are done. + */ + if (result_pos < 0) + break; + } + + if (!anymatch) + { + /* none of patterns matched. */ + break; + } + + string_set_add(str_set, encoded_str); + +#ifdef RPR_DEBUG + elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", + encoded_str->data); +#endif + + /* move to next row */ + pos++; + + if (result_pos < 0) + { + /* out of frame */ + break; + } + } + + if (string_set_get_size(str_set) == 0) + { + /* no match found in the first row */ + register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED); + return; + } + +#ifdef RPR_DEBUG + elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", + pos, encoded_str->data); +#endif + + /* build regular expression */ + pattern_str = makeStringInfo(); + appendStringInfoChar(pattern_str, '^'); + initial_index = 0; + + variable_pos = variable_pos_init(); + + forboth(lc1, winstate->patternVariableList, + lc2, winstate->patternRegexpList) + { + char *vname = strVal(lfirst(lc1)); + char *quantifier = strVal(lfirst(lc2)); + char initial; + + initial = pattern_initial(winstate, vname); + Assert(initial != 0); + appendStringInfoChar(pattern_str, initial); + if (quantifier[0]) + appendStringInfoChar(pattern_str, quantifier[0]); + + /* + * Register the initial at initial_index. If the initial appears more + * than once, all of it's initial_index will be recorded. This could + * happen if a pattern variable appears in the PATTERN clause more + * than once like "UP DOWN UP" "UP UP UP". + */ + variable_pos_register(variable_pos, initial, initial_index); + + initial_index++; + } + +#ifdef RPR_DEBUG + elog(DEBUG2, "pos: " INT64_FORMAT " pattern: %s", + pos, pattern_str->data); +#endif + + /* look for matching pattern variable sequence */ +#ifdef RPR_DEBUG + elog(DEBUG1, "search_str_set started"); +#endif + num_matched_rows = search_str_set(pattern_str->data, + str_set, variable_pos); +#ifdef RPR_DEBUG + elog(DEBUG1, "search_str_set returns: %d", num_matched_rows); +#endif + variable_pos_discard(variable_pos); + string_set_discard(str_set); + + /* + * We are at the first row in the reduced frame. Save the number of + * matched rows as the number of rows in the reduced frame. + */ + if (num_matched_rows <= 0) + { + /* no match */ + register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED); + } + else + { + register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD); + + for (i = original_pos + 1; i < original_pos + num_matched_rows; i++) + { + register_reduced_frame_map(winstate, i, RF_SKIPPED); + } + } + + return; +} + +/* + * search_str_set + * Perform pattern matching using "pattern" against str_set. pattern is a + * regular expression derived from PATTERN clause. Note that the regular + * expression string is prefixed by '^' and followed by initials represented + * in a same way as str_set. str_set is a set of StringInfo. Each StringInfo + * has a string comprising initials of pattern variable strings being true in + * a row. The initials are one of [a-y], parallel to the order of variable + * names in DEFINE clause. Suppose DEFINE has variables START, UP and DOWN. If + * PATTERN has START, UP+ and DOWN, then the initials in PATTERN will be 'a', + * 'b' and 'c'. The "pattern" will be "^ab+c". + * + * variable_pos is an array representing the order of pattern variable string + * initials in PATTERN clause. For example initial 'a' potion is in + * variable_pos[0].pos[0] = 0. Note that if the pattern is "START UP DOWN UP" + * (UP appears twice), then "UP" (initial is 'b') has two position 1 and + * 3. Thus variable_pos for b is variable_pos[1].pos[0] = 1 and + * variable_pos[1].pos[1] = 3. + * + * Returns the longest number of the matching rows (greedy matching) if + * quatifier '+' or '*' is included in "pattern". + */ +static +int +search_str_set(char *pattern, StringSet * str_set, VariablePos * variable_pos) +{ +#define MAX_CANDIDATE_NUM 10000 /* max pattern match candidate size */ +#define FREEZED_CHAR 'Z' /* a pattern is freezed if it ends with the + * char */ +#define DISCARD_CHAR 'z' /* a pattern is not need to keep */ + + int set_size; /* number of rows in the set */ + int resultlen; + int index; + StringSet *old_str_set, + *new_str_set; + int new_str_size; + int len; + + set_size = string_set_get_size(str_set); + new_str_set = string_set_init(); + len = 0; + resultlen = 0; + + /* + * Generate all possible pattern variable name initials as a set of + * StringInfo named "new_str_set". For example, if we have two rows + * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set + * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end. + */ +#ifdef RPR_DEBUG + elog(DEBUG1, "pattern: %s set_size: %d", pattern, set_size); +#endif + for (index = 0; index < set_size; index++) + { + StringInfo str; /* search target row */ + char *p; + int old_set_size; + int i; + +#ifdef RPR_DEBUG + elog(DEBUG1, "index: %d", index); +#endif + if (index == 0) + { + /* copy variables in row 0 */ + str = string_set_get(str_set, index); + p = str->data; + + /* + * Loop over each new pattern variable char. + */ + while (*p) + { + StringInfo new = makeStringInfo(); + + /* add pattern variable char */ + appendStringInfoChar(new, *p); + /* add new one to string set */ + string_set_add(new_str_set, new); +#ifdef RPR_DEBUG + elog(DEBUG1, "old_str: NULL new_str: %s", new->data); +#endif + p++; /* next pattern variable */ + } + } + else /* index != 0 */ + { + old_str_set = new_str_set; + new_str_set = string_set_init(); + str = string_set_get(str_set, index); + old_set_size = string_set_get_size(old_str_set); + + /* + * Loop over each rows in the previous result set. + */ + for (i = 0; i < old_set_size; i++) + { + StringInfo new; + char last_old_char; + int old_str_len; + StringInfo old = string_set_get(old_str_set, i); + + p = old->data; + old_str_len = strlen(p); + if (old_str_len > 0) + last_old_char = p[old_str_len - 1]; + else + last_old_char = '\0'; + + /* Is this old set freezed? */ + if (last_old_char == FREEZED_CHAR) + { + /* if shorter match. we can discard it */ + if ((old_str_len - 1) < resultlen) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "discard this old set because shorter match: %s", + old->data); +#endif + continue; + } + +#ifdef RPR_DEBUG + elog(DEBUG1, "keep this old set: %s", old->data); +#endif + + /* move the old set to new_str_set */ + string_set_add(new_str_set, old); + old_str_set->str_set[i] = NULL; + continue; + } + /* Can this old set be discarded? */ + else if (last_old_char == DISCARD_CHAR) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "discard this old set: %s", old->data); +#endif + continue; + } + +#ifdef RPR_DEBUG + elog(DEBUG1, "str->data: %s", str->data); +#endif + + /* + * loop over each pattern variable initial char in the input + * set. + */ + for (p = str->data; *p; p++) + { + /* + * Optimization. Check if the row's pattern variable + * initial character position is greater than or equal to + * the old set's last pattern variable initial character + * position. For example, if the old set's last pattern + * variable initials are "ab", then the new pattern + * variable initial can be "b" or "c" but can not be "a", + * if the initials in PATTERN is something like "a b c" or + * "a b+ c+" etc. This optimization is possible when we + * only allow "+" quantifier. + */ + if (variable_pos_compare(variable_pos, last_old_char, *p)) + { + /* copy source string */ + new = makeStringInfo(); + enlargeStringInfo(new, old->len + 1); + appendStringInfoString(new, old->data); + /* add pattern variable char */ + appendStringInfoChar(new, *p); +#ifdef RPR_DEBUG + elog(DEBUG1, "old_str: %s new_str: %s", + old->data, new->data); +#endif + + /* + * Adhoc optimization. If the first letter in the + * input string is the first and second position one + * and there's no associated quatifier '+', then we + * can dicard the input because there's no chace to + * expand the string further. + * + * For example, pattern "abc" cannot match "aa". + */ +#ifdef RPR_DEBUG + elog(DEBUG1, "pattern[1]:%c pattern[2]:%c new[0]:%c new[1]:%c", + pattern[1], pattern[2], new->data[0], new->data[1]); +#endif + if (pattern[1] == new->data[0] && + pattern[1] == new->data[1] && + pattern[2] != '+' && + pattern[1] != pattern[2]) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "discard this new data: %s", + new->data); +#endif + pfree(new->data); + pfree(new); + continue; + } + + /* add new one to string set */ + string_set_add(new_str_set, new); + } + else + { + /* + * We are freezing this pattern string. Since there's + * no chance to expand the string further, we perform + * pattern matching against the string. If it does not + * match, we can discard it. + */ + len = do_pattern_match(pattern, old->data); + + if (len <= 0) + { + /* no match. we can discard it */ + continue; + } + + else if (len <= resultlen) + { + /* shorter match. we can discard it */ + continue; + } + else + { + /* match length is the longest so far */ + + int new_index; + + /* remember the longest match */ + resultlen = len; + + /* freeze the pattern string */ + new = makeStringInfo(); + enlargeStringInfo(new, old->len + 1); + appendStringInfoString(new, old->data); + /* add freezed mark */ + appendStringInfoChar(new, FREEZED_CHAR); +#ifdef RPR_DEBUG + elog(DEBUG1, "old_str: %s new_str: %s", old->data, new->data); +#endif + string_set_add(new_str_set, new); + + /* + * Search new_str_set to find out freezed entries + * that have shorter match length. Mark them as + * "discard" so that they are discarded in the + * next round. + */ + + /* new_index_size should be the one before */ + new_str_size = + string_set_get_size(new_str_set) - 1; + + /* loop over new_str_set */ + for (new_index = 0; new_index < new_str_size; + new_index++) + { + char new_last_char; + int new_str_len; + + new = string_set_get(new_str_set, new_index); + new_str_len = strlen(new->data); + if (new_str_len > 0) + { + new_last_char = + new->data[new_str_len - 1]; + if (new_last_char == FREEZED_CHAR && + (new_str_len - 1) <= len) + { + /* + * mark this set to discard in the + * next round + */ + appendStringInfoChar(new, DISCARD_CHAR); +#ifdef RPR_DEBUG + elog(DEBUG1, "add discard char: %s", new->data); +#endif + } + } + } + } + } + } + } + /* we no longer need old string set */ + string_set_discard(old_str_set); + } + } + + /* + * Perform pattern matching to find out the longest match. + */ + new_str_size = string_set_get_size(new_str_set); +#ifdef RPR_DEBUG + elog(DEBUG1, "new_str_size: %d", new_str_size); +#endif + len = 0; + resultlen = 0; + + for (index = 0; index < new_str_size; index++) + { + StringInfo s; + + s = string_set_get(new_str_set, index); + if (s == NULL) + continue; /* no data */ + +#ifdef RPR_DEBUG + elog(DEBUG1, "target string: %s", s->data); +#endif + len = do_pattern_match(pattern, s->data); + if (len > resultlen) + { + /* remember the longest match */ + resultlen = len; + + /* + * If the size of result set is equal to the number of rows in the + * set, we are done because it's not possible that the number of + * matching rows exceeds the number of rows in the set. + */ + if (resultlen >= set_size) + break; + } + } + + /* we no longer need new string set */ + string_set_discard(new_str_set); + + return resultlen; +} + +/* + * do_pattern_match + * perform pattern match using pattern against encoded_str. + * returns matching number of rows if matching is succeeded. + * Otherwise returns 0. + */ +static +int +do_pattern_match(char *pattern, char *encoded_str) +{ + Datum d; + text *res; + char *substr; + int len = 0; + text *pattern_text, + *encoded_str_text; + + pattern_text = cstring_to_text(pattern); + encoded_str_text = cstring_to_text(encoded_str); + + /* + * We first perform pattern matching using regexp_instr, then call + * textregexsubstr to get matched substring to know how long the matched + * string is. That is the number of rows in the reduced window frame. The + * reason why we can't call textregexsubstr in the first place is, it + * errors out if pattern does not match. + */ + if (DatumGetInt32(DirectFunctionCall2Coll( + regexp_instr, DEFAULT_COLLATION_OID, + PointerGetDatum(encoded_str_text), + PointerGetDatum(pattern_text)))) + { + d = DirectFunctionCall2Coll(textregexsubstr, + DEFAULT_COLLATION_OID, + PointerGetDatum(encoded_str_text), + PointerGetDatum(pattern_text)); + if (d != 0) + { + res = DatumGetTextPP(d); + substr = text_to_cstring(res); + len = strlen(substr); + pfree(substr); + } + } + pfree(encoded_str_text); + pfree(pattern_text); + + return len; +} + +/* + * evaluate_pattern + * Evaluate expression associated with PATTERN variable vname. current_pos is + * relative row position in a frame (starting from 0). If vname is evaluated + * to true, initial letters associated with vname is appended to + * encode_str. result is out paramater representing the expression evaluation + * result is true of false. + *--------- + * Return values are: + * >=0: the last match absolute row position + * otherwise out of frame. + *--------- + */ +static +int64 +evaluate_pattern(WindowObject winobj, int64 current_pos, + char *vname, StringInfo encoded_str, bool *result) +{ + WindowAggState *winstate = winobj->winstate; + ExprContext *econtext = winstate->ss.ps.ps_ExprContext; + ListCell *lc1, + *lc2, + *lc3; + ExprState *pat; + Datum eval_result; + bool out_of_frame = false; + bool isnull; + TupleTableSlot *slot; + + forthree(lc1, winstate->defineVariableList, + lc2, winstate->defineClauseList, + lc3, winstate->defineInitial) + { + char initial; /* initial letter associated with vname */ + char *name = strVal(lfirst(lc1)); + + if (strcmp(vname, name)) + continue; + + initial = *(strVal(lfirst(lc3))); + + /* set expression to evaluate */ + pat = lfirst(lc2); + + /* get current, previous and next tuples */ + if (!get_slots(winobj, current_pos)) + { + out_of_frame = true; + } + else + { + /* evaluate the expression */ + eval_result = ExecEvalExpr(pat, econtext, &isnull); + if (isnull) + { + /* expression is NULL */ +#ifdef RPR_DEBUG + elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, + vname, current_pos); +#endif + *result = false; + } + else + { + if (!DatumGetBool(eval_result)) + { + /* expression is false */ +#ifdef RPR_DEBUG + elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, + vname, current_pos); +#endif + *result = false; + } + else + { + /* expression is true */ +#ifdef RPR_DEBUG + elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, + vname, current_pos); +#endif + appendStringInfoChar(encoded_str, initial); + *result = true; + } + } + + slot = winstate->temp_slot_1; + if (slot != winstate->null_slot) + ExecClearTuple(slot); + slot = winstate->prev_slot; + if (slot != winstate->null_slot) + ExecClearTuple(slot); + slot = winstate->next_slot; + if (slot != winstate->null_slot) + ExecClearTuple(slot); + + break; + } + + if (out_of_frame) + { + *result = false; + return -1; + } + } + return current_pos; +} + +/* + * get_slots + * Get current, previous and next tuples. + * Returns false if current row is out of partition/full frame. + */ +static +bool +get_slots(WindowObject winobj, int64 current_pos) +{ + WindowAggState *winstate = winobj->winstate; + TupleTableSlot *slot; + int ret; + ExprContext *econtext; + + econtext = winstate->ss.ps.ps_ExprContext; + + /* set up current row tuple slot */ + slot = winstate->temp_slot_1; + if (!window_gettupleslot(winobj, current_pos, slot)) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, + current_pos); +#endif + return false; + } + ret = row_is_in_frame(winstate, current_pos, slot); + if (ret <= 0) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, + current_pos); +#endif + ExecClearTuple(slot); + return false; + } + econtext->ecxt_outertuple = slot; + + /* for PREV */ + if (current_pos > 0) + { + slot = winstate->prev_slot; + if (!window_gettupleslot(winobj, current_pos - 1, slot)) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, + current_pos - 1); +#endif + econtext->ecxt_scantuple = winstate->null_slot; + } + else + { + ret = row_is_in_frame(winstate, current_pos - 1, slot); + if (ret <= 0) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, + current_pos - 1); +#endif + ExecClearTuple(slot); + econtext->ecxt_scantuple = winstate->null_slot; + } + else + { + econtext->ecxt_scantuple = slot; + } + } + } + else + econtext->ecxt_scantuple = winstate->null_slot; + + /* for NEXT */ + slot = winstate->next_slot; + if (!window_gettupleslot(winobj, current_pos + 1, slot)) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, + current_pos + 1); +#endif + econtext->ecxt_innertuple = winstate->null_slot; + } + else + { + ret = row_is_in_frame(winstate, current_pos + 1, slot); + if (ret <= 0) + { +#ifdef RPR_DEBUG + elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, + current_pos + 1); +#endif + ExecClearTuple(slot); + econtext->ecxt_innertuple = winstate->null_slot; + } + else + econtext->ecxt_innertuple = slot; + } + return true; +} + +/* + * pattern_initial + * Return pattern variable initial character + * matching with pattern variable name vname. + * If not found, return 0. + */ +static +char +pattern_initial(WindowAggState *winstate, char *vname) +{ + char initial; + char *name; + ListCell *lc1, + *lc2; + + forboth(lc1, winstate->defineVariableList, + lc2, winstate->defineInitial) + { + name = strVal(lfirst(lc1)); /* DEFINE variable name */ + initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */ + + + if (!strcmp(name, vname)) + return initial; /* found */ + } + return 0; +} + +/* + * string_set_init + * Create dynamic set of StringInfo. + */ +static +StringSet * string_set_init(void) +{ +/* Initial allocation size of str_set */ +#define STRING_SET_ALLOC_SIZE 1024 + + StringSet *string_set; + Size set_size; + + string_set = palloc0(sizeof(StringSet)); + string_set->set_index = 0; + set_size = STRING_SET_ALLOC_SIZE; + string_set->str_set = palloc(set_size * sizeof(StringInfo)); + string_set->set_size = set_size; + + return string_set; +} + +/* + * string_set_add + * Add StringInfo str to StringSet string_set. + */ +static +void +string_set_add(StringSet * string_set, StringInfo str) +{ + Size set_size; + + set_size = string_set->set_size; + if (string_set->set_index >= set_size) + { + set_size *= 2; + string_set->str_set = repalloc(string_set->str_set, + set_size * sizeof(StringInfo)); + string_set->set_size = set_size; + } + + string_set->str_set[string_set->set_index++] = str; + + return; +} + +/* + * string_set_get + * Returns StringInfo specified by index. + * If there's no data yet, returns NULL. + */ +static +StringInfo +string_set_get(StringSet * string_set, int index) +{ + /* no data? */ + if (index == 0 && string_set->set_index == 0) + return NULL; + + if (index < 0 || index >= string_set->set_index) + elog(ERROR, "invalid index: %d", index); + + return string_set->str_set[index]; +} + +/* + * string_set_get_size + * Returns the size of StringSet. + */ +static +int +string_set_get_size(StringSet * string_set) +{ + return string_set->set_index; +} + +/* + * string_set_discard + * Discard StringSet. + * All memory including StringSet itself is freed. + */ +static +void +string_set_discard(StringSet * string_set) +{ + int i; + + for (i = 0; i < string_set->set_index; i++) + { + StringInfo str = string_set->str_set[i]; + + if (str) + { + pfree(str->data); + pfree(str); + } + } + pfree(string_set->str_set); + pfree(string_set); +} + +/* + * variable_pos_init + * Create and initialize variable postion structure + */ +static +VariablePos * variable_pos_init(void) +{ + VariablePos *variable_pos; + + variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS); + MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS); + return variable_pos; +} + +/* + * variable_pos_register + * Register pattern variable whose initial is initial into postion index. + * pos is position of initial. + * If pos is already registered, register it at next empty slot. + */ +static +void +variable_pos_register(VariablePos * variable_pos, char initial, int pos) +{ + int index = initial - 'a'; + int slot; + int i; + + if (pos < 0 || pos > NUM_ALPHABETS) + elog(ERROR, "initial is not valid char: %c", initial); + + for (i = 0; i < NUM_ALPHABETS; i++) + { + slot = variable_pos[index].pos[i]; + if (slot < 0) + { + /* empty slot found */ + variable_pos[index].pos[i] = pos; + return; + } + } + elog(ERROR, "no empty slot for initial: %c", initial); +} + +/* + * variable_pos_compare + * Returns true if initial1 can be followed by initial2 + */ +static +bool +variable_pos_compare(VariablePos * variable_pos, char initial1, char initial2) +{ + int index1, + index2; + int pos1, + pos2; + + for (index1 = 0;; index1++) + { + pos1 = variable_pos_fetch(variable_pos, initial1, index1); + if (pos1 < 0) + break; + + for (index2 = 0;; index2++) + { + pos2 = variable_pos_fetch(variable_pos, initial2, index2); + if (pos2 < 0) + break; + if (pos1 <= pos2) + return true; + } + } + return false; +} + +/* + * variable_pos_fetch + * Fetch position of pattern variable whose initial is initial, and whose index + * is index. If no postion was registered by initial, index, returns -1. + */ +static +int +variable_pos_fetch(VariablePos * variable_pos, char initial, int index) +{ + int pos = initial - 'a'; + + if (pos < 0 || pos > NUM_ALPHABETS) + elog(ERROR, "initial is not valid char: %c", initial); + + if (index < 0 || index > NUM_ALPHABETS) + elog(ERROR, "index is not valid: %d", index); + + return variable_pos[pos].pos[index]; +} + +/* + * variable_pos_discard + * Discard VariablePos + */ +static +void +variable_pos_discard(VariablePos * variable_pos) +{ + pfree(variable_pos); +} diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c index 473c61569f..92c528d38c 100644 --- a/src/backend/utils/adt/windowfuncs.c +++ b/src/backend/utils/adt/windowfuncs.c @@ -13,6 +13,9 @@ */ #include "postgres.h" +#include "catalog/pg_collation_d.h" +#include "executor/executor.h" +#include "nodes/execnodes.h" #include "nodes/parsenodes.h" #include "nodes/supportnodes.h" #include "utils/fmgrprotos.h" @@ -37,11 +40,19 @@ typedef struct int64 remainder; /* (total rows) % (bucket num) */ } ntile_context; +/* + * rpr process information. + * Used for AFTER MATCH SKIP PAST LAST ROW + */ +typedef struct SkipContext +{ + int64 pos; /* last row absolute position */ +} SkipContext; + static bool rank_up(WindowObject winobj); static Datum leadlag_common(FunctionCallInfo fcinfo, bool forward, bool withoffset, bool withdefault); - /* * utility routine for *_rank functions. */ @@ -674,7 +685,7 @@ window_last_value(PG_FUNCTION_ARGS) bool isnull; result = WinGetFuncArgInFrame(winobj, 0, - 0, WINDOW_SEEK_TAIL, true, + 0, WINDOW_SEEK_TAIL, false, &isnull, NULL); if (isnull) PG_RETURN_NULL(); @@ -714,3 +725,25 @@ window_nth_value(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } + +/* + * prev + * Dummy function to invoke RPR's navigation operator "PREV". + * This is *not* a window function. + */ +Datum +window_prev(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(PG_GETARG_DATUM(0)); +} + +/* + * next + * Dummy function to invoke RPR's navigation operation "NEXT". + * This is *not* a window function. + */ +Datum +window_next(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(PG_GETARG_DATUM(0)); +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 134e3b22fd..5f7fb538f9 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -10477,6 +10477,12 @@ { oid => '3114', descr => 'fetch the Nth row value', proname => 'nth_value', prokind => 'w', prorettype => 'anyelement', proargtypes => 'anyelement int4', prosrc => 'window_nth_value' }, +{ oid => '6122', descr => 'previous value', + proname => 'prev', provolatile => 's', prorettype => 'anyelement', + proargtypes => 'anyelement', prosrc => 'window_prev' }, +{ oid => '6123', descr => 'next value', + proname => 'next', provolatile => 's', prorettype => 'anyelement', + proargtypes => 'anyelement', prosrc => 'window_next' }, # functions for range types { oid => '3832', descr => 'I/O', diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index d927ac44a8..971d8682b1 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2550,6 +2550,11 @@ typedef enum WindowAggStatus * tuples during spool */ } WindowAggStatus; +#define RF_NOT_DETERMINED 0 +#define RF_FRAME_HEAD 1 +#define RF_SKIPPED 2 +#define RF_UNMATCHED 3 + typedef struct WindowAggState { ScanState ss; /* its first field is NodeTag */ @@ -2598,6 +2603,19 @@ typedef struct WindowAggState int64 groupheadpos; /* current row's peer group head position */ int64 grouptailpos; /* " " " " tail position (group end+1) */ + /* these fields are used in Row pattern recognition: */ + RPSkipTo rpSkipTo; /* Row Pattern Skip To type */ + List *patternVariableList; /* list of row pattern variables names + * (list of String) */ + List *patternRegexpList; /* list of row pattern regular expressions + * ('+' or ''. list of String) */ + List *defineVariableList; /* list of row pattern definition + * variables (list of String) */ + List *defineClauseList; /* expression for row pattern definition + * search conditions ExprState list */ + List *defineInitial; /* list of row pattern definition variable + * initials (list of String) */ + MemoryContext partcontext; /* context for partition-lifespan data */ MemoryContext aggcontext; /* shared context for aggregate working data */ MemoryContext curaggcontext; /* current aggregate's working data */ @@ -2634,6 +2652,18 @@ typedef struct WindowAggState TupleTableSlot *agg_row_slot; TupleTableSlot *temp_slot_1; TupleTableSlot *temp_slot_2; + + /* temporary slots for RPR */ + TupleTableSlot *prev_slot; /* PREV row navigation operator */ + TupleTableSlot *next_slot; /* NEXT row navigation operator */ + TupleTableSlot *null_slot; /* all NULL slot */ + + /* + * Each byte corresponds to a row positioned at absolute its pos in + * partition. See above definition for RF_* + */ + char *reduced_frame_map; + int64 alloc_sz; /* size of the map */ } WindowAggState; /* ---------------- -- 2.25.1 ----Next_Part(Sun_Apr_28_20_28_26_2024_444)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v17-0006-Row-pattern-recognition-patch-docs.patch" ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/connectdb.c | 4 +- src/bin/pg_dump/pg_dump.c | 334 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 5 files changed, 23 insertions(+), 359 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/connectdb.c b/src/bin/pg_dump/connectdb.c index f3ce8b1cfb1..d145308dccf 100644 --- a/src/bin/pg_dump/connectdb.c +++ b/src/bin/pg_dump/connectdb.c @@ -212,11 +212,11 @@ ConnectDatabase(const char *dbname, const char *connection_string, my_version = PG_VERSION_NUM; /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dump.c.) */ if (my_version != server_version_temp - && (server_version_temp < 90200 || + && (server_version_temp < 100000 || (server_version_temp / 100) > (my_version / 100))) { pg_log_error("aborting because of server version mismatch"); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..65bd15ebfd2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,13 +1933,11 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs + * Mark the member object to have any non-initial ACLs * dumped. (Any initial ACLs will be removed later, using data from * pg_init_privs, so that we'll dump only the delta from the extension's * initial setup.) * - * Prior to 9.6, we do not include any extension member components. - * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database * contents rather than replace the extension contents with something @@ -1964,12 +1953,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1984,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2196,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2213,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3098,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3296,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3638,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4205,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4274,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4489,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4852,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5142,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6630,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6821,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6856,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6938,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6957,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7004,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7252,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7294,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7868,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8154,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8820,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9086,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9313,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10717,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10784,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10958,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11128,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11140,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11148,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13469,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14963,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15372,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15383,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16848,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16872,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19161,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19222,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19414,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --aHl3HfeiUuO3zeNC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --6vzYk1swa63ey9i6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index a0f7f8e2168..75c27a08540 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --2xrO7hiVfr8aWtYg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 28 --- 4 files changed, 20 insertions(+), 354 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 0e0d53926af..774be23b4f9 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1717,7 +1705,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index dfa292c2c3a..d9984910cc4 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c56437d6057..17ad8eeb838 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b9653f0aefe..e68937c9934 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -785,17 +785,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -849,7 +843,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -860,27 +853,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --ZcI1PtyEAe3VcVeQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v5-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
* [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 @ 2026-04-17 17:15 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 466+ messages in thread From: Nathan Bossart @ 2026-04-17 17:15 UTC (permalink / raw) --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/runtime.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 330 ++-------------------------------- src/bin/pg_dump/pg_dumpall.c | 32 +--- 4 files changed, 22 insertions(+), 356 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so <application>pg_dump</application> has no choice but to abort the dump. </para> - <para> - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - <productname>PostgreSQL</productname> 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - <command>pg_dump -j</command> uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - </para> </listitem> </varlistentry> @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; <productname>PostgreSQL</productname> server versions newer than <application>pg_dump</application>'s version. <application>pg_dump</application> can also dump from <productname>PostgreSQL</productname> servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, <application>pg_dump</application> cannot dump from <productname>PostgreSQL</productname> servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index b01e74638c4..3fa6cdf3a5e 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1776,7 +1776,7 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput version of <productname>PostgreSQL</productname>, to take advantage of enhancements that might have been made in these programs. Current releases of the - dump programs can read data from any server version back to 9.2. + dump programs can read data from any server version back to 10. </para> <para> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d56dcc701ce..eed9aaeb7c1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,9 +1491,7 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { if (dopt->enable_row_security) ExecuteSqlStatement(AH, "SET row_security = on"); else ExecuteSqlStatement(AH, "SET row_security = off"); - } /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1964,12 +1955,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } return true; } @@ -2000,11 +1986,10 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* - * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if + * We dump out any ACLs defined in pg_catalog, if * they are interesting (and not the original ACLs which were set at * initdb time, see pg_init_privs). */ @@ -2213,8 +2198,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2215,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3100,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3325,10 +3298,7 @@ dumpDatabase(Archive *fout) "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3640,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" "FROM pg_catalog.pg_class\n" "WHERE oid IN (%u, %u, %u, %u);\n", LargeObjectRelationId, LargeObjectLOidPNIndexId, LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4207,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4316,10 +4276,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) printfPQExpBuffer(query, "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); appendPQExpBuffer(query, "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " @@ -4534,7 +4491,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4854,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5144,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,24 +6632,12 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. + * Select all access methods from pg_am table. */ appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "amtype, " "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); appendPQExpBufferStr(query, "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6878,15 +6823,12 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" : "p.proisagg"); @@ -6916,29 +6858,6 @@ getAggregates(Archive *fout) "refclassid = 'pg_extension'::regclass AND " "deptype = 'e')"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7021,6 +6940,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7039,14 +6959,10 @@ getFuncs(Archive *fout) * include them, since we want to dump extension members individually in * that mode. Also, if they are used by casts or transforms then we need * to gather the information about them, though they won't be dumped if - * they are built-in. Also, in 9.6 and up, include functions in + * they are built-in. Also, include functions in * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" : "NOT p.proisagg"); @@ -7090,46 +7006,6 @@ getFuncs(Archive *fout) appendPQExpBufferStr(query, "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - appendPQExpBufferStr(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBufferChar(query, ')'); - } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7378,64 +7254,31 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relispopulated, "); - else - appendPQExpBufferStr(query, - "'t' as relispopulated, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "c.relreplident, "); - else - appendPQExpBufferStr(query, - "'d' AS relreplident, "); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - if (fout->remoteVersion >= 90300) appendPQExpBufferStr(query, "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "); - else - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,9 +7296,8 @@ getTables(Archive *fout, int *numTables) "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); /* - * In 9.6 and up, left join to pg_am to pick up the amname. + * Left join to pg_am to pick up the amname. */ - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); @@ -8028,12 +7870,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.reloptions AS indreloptions, "); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8318,10 +8156,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8988,10 +8822,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9258,10 +9088,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9489,12 +9315,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(q, "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10897,8 +10719,6 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { printfPQExpBuffer(query, "SELECT objoid, classoid, objsubid, privtype, initprivs " "FROM pg_init_privs"); @@ -10966,7 +10786,6 @@ getAdditionalACLs(Archive *fout) } } PQclear(res); - } destroyPQExpBuffer(query); } @@ -11141,15 +10960,6 @@ fetchAttributeStats(Archive *fout) static bool restarted; int max_rels = MAX_ATTR_STATS_RELS; - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; - /* If we're just starting, set our TOC pointer. */ if (!te) te = AH->toc->next; @@ -11320,16 +11130,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For versions before 19, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11337,7 +11142,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11345,12 +11150,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13672,19 +13471,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" "proleakproof,\n"); - if (fout->remoteVersion >= 90500) appendPQExpBufferStr(query, "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15174,14 +14965,9 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) /* Get collation-specific details */ appendPQExpBufferStr(query, "SELECT "); - if (fout->remoteVersion >= 100000) appendPQExpBufferStr(query, "collprovider, " "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15588,7 +15374,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - if (fout->remoteVersion >= 90400) appendPQExpBufferStr(query, "aggkind,\n" "aggmtransfn,\n" @@ -15600,31 +15385,12 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "aggtransspace,\n" "aggmtransspace,\n" "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - if (fout->remoteVersion >= 90600) appendPQExpBufferStr(query, "aggcombinefn,\n" "aggserialfn,\n" "aggdeserialfn,\n" "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17084,8 +16850,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) appendPQExpBufferStr(query, "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - if (fout->remoteVersion >= 90600) - { /* * In principle we should call acldefault('c', relowner) to * get the default ACL for a column. However, we don't @@ -17110,17 +16874,6 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) "NOT at.attisdropped " "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } ExecuteSqlStatement(fout, query->data); @@ -19410,16 +19163,10 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || + if (fout->remoteVersion < 180000 || (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " @@ -19477,59 +19224,20 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted + * The sequence information is gathered in a sorted * table before any calls to dumpSequence(). See collectSequences() for * more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - Assert(sequences); key.oid = tbinfo->dobj.catId.oid; seq = bsearch(&key, sequences, nsequences, sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); - - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19708,8 +19416,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index c1f43113c53..5b10f7122b7 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; @@ -954,17 +954,11 @@ dropRoles(PGconn *conn) int i_rolname; int i; - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT rolname " "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 1", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT rolname " - "FROM %s " - "ORDER BY 1", role_catalog); res = executeQuery(conn, buf->data); @@ -1041,7 +1035,6 @@ dumpRoles(PGconn *conn) * Notes: rolconfig is dumped later, and pg_authid must be used for * extracting rolcomment regardless of role_catalog. */ - if (server_version >= 90600) printfPQExpBuffer(buf, "SELECT oid, rolname, rolsuper, rolinherit, " "rolcreaterole, rolcreatedb, " @@ -1052,27 +1045,6 @@ dumpRoles(PGconn *conn) "FROM %s " "WHERE rolname !~ '^pg_' " "ORDER BY 2", role_catalog); - else if (server_version >= 90500) - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); - else - printfPQExpBuffer(buf, - "SELECT oid, rolname, rolsuper, rolinherit, " - "rolcreaterole, rolcreatedb, " - "rolcanlogin, rolconnlimit, rolpassword, " - "rolvaliduntil, rolreplication, " - "false as rolbypassrls, " - "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, " - "rolname = current_user AS is_current_user " - "FROM %s " - "ORDER BY 2", role_catalog); res = executeQuery(conn, buf->data); -- 2.50.1 (Apple Git-155) --CT89ko5pLUrsvFtH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-pg_upgrade-bump-minimum-supported-version-to-v10.patch ^ permalink raw reply [nested|flat] 466+ messages in thread
end of thread, other threads:[~2026-04-17 17:15 UTC | newest] Thread overview: 466+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2023-08-07 23:56 [PATCH v3 09/10] ci: windows: Disabling write cache flushing during test Andres Freund <[email protected]> 2023-08-07 23:56 [PATCH v3 09/10] ci: windows: Disabling write cache flushing during test Andres Freund <[email protected]> 2023-08-07 23:56 [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test Andres Freund <[email protected]> 2023-08-07 23:56 [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test Andres Freund <[email protected]> 2023-08-07 23:56 [PATCH v1 6/9] ci: windows: Disabling write cache flushing during test Andres Freund <[email protected]> 2024-04-28 11:00 [PATCH v17 5/8] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v6 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v3 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v4 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v5 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]> 2026-04-17 17:15 [PATCH v2 1/4] pg_dump/pg_dumpall: bump minimum supported version to v10 Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox